<!--
 * @description: 编辑阵营
 * @fileName: EditCampDialog.vue
 * @author: ssr
 * @date: 2023-01-05 15:04:49
 * @version: V1.0.0
! -->
<script setup lang="ts">
import type { FormInstance, FormRules } from "element-plus"
import { FormTypeEnum } from "@/common/constants/other-keys"
import { useScenarioStore } from "@/pinia/stores/scenario"
import { getCamp, isRepeatCampLabelValue, saveCamp, updateCamp } from "@@/apis/scn"
import { ElMessage } from "element-plus"
import { isString } from "lodash-es"
import { nextTick, reactive, ref } from "vue"

const props = withDefaults(defineProps<Props>(), {
  dialogType: FormTypeEnum.CREATE,
  campId: ""
})

const emit = defineEmits(["updateCamp"])

interface Props {
  dialogType: FormTypeEnum
  campId: string
}

interface ICampItem {
  id: string
  label: string
  value: string
  color: string
}

// 状态和引用
const scenarioStore = useScenarioStore()
const formRef = ref<FormInstance>()
const visible = ref(false)
const confirmLoading = ref(false)
const formState = reactive<ICampItem>({
  id: "",
  label: "",
  value: "",
  color: "#409EFF" // Element Plus 默认主色
})
const oldColor = ref("")

// 表单验证规则
const rules = reactive<FormRules>({
  label: [
    { required: true, message: "请输入阵营名称", trigger: "blur" },
    { validator: handleValidator, trigger: "blur" }
  ],
  value: [
    { required: true, message: "请输入阵营编码", trigger: "blur" },
    { validator: handleValidatorValue, trigger: "blur" }
  ],
  color: [
    { required: true, message: "请选择颜色", trigger: "change" }
  ]
})

// 显示对话框
function handleShowDialog() {
  if (props.dialogType === FormTypeEnum.CREATE) {
    handleAddDialog()
  } else if (props.dialogType === FormTypeEnum.EDIT && props.campId) {
    handleEditDialog()
  }
}

// 编辑对话框
async function handleEditDialog() {
  try {
    const campDetail = await handleCampDetail()
    if (campDetail) {
      visible.value = true
      nextTick(() => {
        formRef.value?.clearValidate()
      })
    }
  } catch (error) {
    console.error("获取阵营详情失败:", error)
    ElMessage.error("获取阵营详情失败")
  }
}

// 新增对话框
function handleAddDialog() {
  Object.assign(formState, {
    id: "",
    label: "",
    value: "",
    color: "#409EFF"
  })
  oldColor.value = formState.color
  visible.value = true
  nextTick(() => {
    formRef.value?.clearValidate()
  })
}

// 获取阵营详情
async function handleCampDetail() {
  try {
    const { data } = await getCamp(props.campId)
    if (data) {
      Object.assign(formState, data)
      oldColor.value = formState.color
      return data
    }
    return null
  } catch (error) {
    console.error("获取阵营详情失败:", error)
    ElMessage.error("获取阵营详情失败")
    return null
  }
}

// 验证阵营名称
async function handleValidator(_rule: any, value: string, callback: any) {
  if (!value) {
    callback(new Error("请输入阵营名称"))
    return
  }

  try {
    const params = {
      scnId: scenarioStore.scnId,
      id: formState.id,
      label: value
    }

    const { data } = await isRepeatCampLabelValue(params)
    if (data) {
      callback(new Error("该名称已存在"))
    } else {
      callback()
    }
  } catch (error) {
    console.error("验证阵营名称失败:", error)
    callback(new Error("验证失败"))
  }
}

// 验证阵营编码
async function handleValidatorValue(_rule: any, value: string, callback: any) {
  if (!value) {
    callback(new Error("请输入阵营编码"))
    return
  }

  try {
    const params = {
      scnId: scenarioStore.scnId,
      id: formState.id,
      value
    }
    const { data } = await isRepeatCampLabelValue(params)
    if (data) {
      callback(new Error("该编码已存在"))
    } else {
      callback()
    }
  } catch (error) {
    console.error("验证阵营编码失败:", error)
    callback(new Error("验证失败"))
  }
}

// 确认保存
async function handleConfirm() {
  if (!formRef.value) return

  try {
    await formRef.value.validate()
    confirmLoading.value = true

    const params = {
      scnId: scenarioStore.scnId,
      ...(formState.id ? { id: formState.id } : {}),
      value: formState.value,
      label: formState.label,
      color: formState.color
    }

    if (props.dialogType === FormTypeEnum.CREATE) {
      await saveCamp(params)
      ElMessage.success("新增阵营成功")
    } else {
      await updateCamp(params)
      ElMessage.success("更新阵营成功")
    }

    visible.value = false
    emit("updateCamp")
  } catch (error) {
    console.error("保存阵营失败:", error)
    if (isString(error)) {
      ElMessage.error(error)
    } else {
      ElMessage.error("保存失败")
    }
  } finally {
    confirmLoading.value = false
  }
}

// 取消
function handleCancel() {
  visible.value = false
}

// 暴露方法给父组件
defineExpose({
  handleShowDialog
})
</script>

<template>
  <el-dialog
    v-model="visible"
    :title="dialogType === FormTypeEnum.CREATE ? '新建阵营' : '编辑阵营'"
    width="500px"
    :close-on-click-modal="false"
    :close-on-press-escape="false"
  >
    <el-form
      ref="formRef"
      :model="formState"
      :rules="rules"
      label-width="80px"
      label-position="right"
      status-icon
    >
      <el-form-item label="名称" prop="label">
        <el-input v-model="formState.label" placeholder="请输入阵营名称" />
      </el-form-item>

      <el-form-item label="编码" prop="value">
        <el-input v-model="formState.value" placeholder="请输入阵营编码" />
      </el-form-item>

      <el-form-item label="颜色" prop="color">
        <el-color-picker
          v-model="formState.color"
          :disabled="dialogType === FormTypeEnum.EDIT"
        />
      </el-form-item>
    </el-form>

    <template #footer>
      <span class="dialog-footer">
        <el-button @click="handleCancel">取消</el-button>
        <el-button type="primary" @click="handleConfirm" :loading="confirmLoading">
          确定
        </el-button>
      </span>
    </template>
  </el-dialog>
</template>

<style lang="scss" scoped>
.dialog-footer {
  display: flex;
  justify-content: flex-end;
  gap: 10px;
}

:deep(.el-dialog__body) {
  padding-top: 20px;
  padding-bottom: 10px;
}
</style>
